package com.yfqy.admin.conf;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Configuration
public class ThreadPoolConfig implements DisposableBean {

    private static final int CORE_POOL_SIZE = 10;
    private static final int MAX_POOL_SIZE = 100;
    private static final long KEEP_ALIVE_TIME = 60L;
    private static final int QUEUE_CAPACITY = 1000;
    private static final String THREAD_NAME_PREFIX = "DefaultThreadPoolExecutor-";

    private ThreadPoolExecutor threadPoolExecutor;


    @Bean(name = "defaultThreadPoolExecutor")
    public ThreadPoolExecutor threadPoolExecutor() {
        this.threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(QUEUE_CAPACITY),
                new CustomThreadFactory(THREAD_NAME_PREFIX),
                new ThreadPoolExecutor.CallerRunsPolicy()  // 添加拒绝策略:由提交任务的线程自己执行
        );
        return threadPoolExecutor;
    }

    @Override
    public void destroy() {
        shutdownThreadPoolGracefully();
    }

    private void shutdownThreadPoolGracefully() {
        if (threadPoolExecutor != null) {
            // 禁止新任务提交
            threadPoolExecutor.shutdown();
            try {
                if (!threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                    // 取消当前执行的任务
                    threadPoolExecutor.shutdownNow();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                threadPoolExecutor.shutdownNow();
            }
        }
    }

    /**
     * 自定义线程工厂（命名优化）
     */
    private static class CustomThreadFactory implements ThreadFactory {
        private final String namePrefix;
        private final AtomicInteger threadCount = new AtomicInteger(1);

        CustomThreadFactory(String namePrefix) {
            this.namePrefix = namePrefix;
        }

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, namePrefix + threadCount.getAndIncrement());
        }
    }
}
